"""
空间占用检测API接口
"""
from fastapi import APIRouter, HTTPException, Depends, UploadFile, File
from typing import List, Optional
import base64
import cv2
import numpy as np
from datetime import datetime

from schemas.space_occupancy import (
    SpaceOccupancyRequest,
    SpaceOccupancyResponse,
    SpaceConfigRequest,
    SpaceConfigResponse,
    SpaceUsageStatsResponse,
    SpaceServiceStatsResponse,
    SpaceOccupancyListRequest,
    SpaceOccupancyListResponse,
    SpaceUsageStatsRequest,
    EnergyRecommendationRequest,
    SpaceConfigListResponse,
    EnergyRecommendationListResponse
)
from services.space_occupancy_service import (
    space_occupancy_service,
    SpaceConfig
)

router = APIRouter(prefix="/space-occupancy", tags=["空间占用检测"])


@router.post("/detect", response_model=SpaceOccupancyResponse)
async def detect_space_occupancy(request: SpaceOccupancyRequest):
    """
    检测空间占用状态
    """
    try:
        # 解码图像数据
        if request.image_data:
            # 从Base64解码图像
            image_bytes = base64.b64decode(request.image_data)
            nparr = np.frombuffer(image_bytes, np.uint8)
            image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
        else:
            # 如果没有提供图像，创建一个模拟图像
            image = np.random.randint(0, 255, (480, 640, 3), dtype=np.uint8)
        
        # 执行空间占用检测
        result = await space_occupancy_service.detect_space_occupancy(
            image=image,
            camera_id=request.camera_id,
            space_id=request.space_id
        )
        
        # 转换为响应格式
        return SpaceOccupancyResponse(
            detection_id=result.detection_id,
            camera_id=result.camera_id,
            space_id=result.space_id,
            timestamp=result.timestamp,
            occupancy_status=result.occupancy_status,
            occupancy_rate=result.occupancy_rate,
            person_count=result.person_count,
            capacity=result.capacity,
            space_type=result.space_type,
            confidence=result.confidence,
            detected_activities=result.detected_activities,
            energy_recommendations=result.energy_recommendations,
            usage_duration=result.usage_duration
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"空间占用检测失败: {str(e)}")


@router.post("/detect/upload", response_model=SpaceOccupancyResponse)
async def detect_occupancy_from_upload(
    camera_id: str,
    space_id: str,
    file: UploadFile = File(...)
):
    """
    通过上传图像检测空间占用状态
    """
    try:
        # 读取上传的图像文件
        contents = await file.read()
        nparr = np.frombuffer(contents, np.uint8)
        image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
        
        if image is None:
            raise HTTPException(status_code=400, detail="无效的图像文件")
        
        # 执行空间占用检测
        result = await space_occupancy_service.detect_space_occupancy(
            image=image,
            camera_id=camera_id,
            space_id=space_id
        )
        
        # 转换为响应格式
        return SpaceOccupancyResponse(
            detection_id=result.detection_id,
            camera_id=result.camera_id,
            space_id=result.space_id,
            timestamp=result.timestamp,
            occupancy_status=result.occupancy_status,
            occupancy_rate=result.occupancy_rate,
            person_count=result.person_count,
            capacity=result.capacity,
            space_type=result.space_type,
            confidence=result.confidence,
            detected_activities=result.detected_activities,
            energy_recommendations=result.energy_recommendations,
            usage_duration=result.usage_duration
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"空间占用检测失败: {str(e)}")


@router.post("/detections", response_model=SpaceOccupancyListResponse)
async def get_detection_results(request: SpaceOccupancyListRequest):
    """
    获取空间占用检测结果列表
    """
    try:
        results = await space_occupancy_service.get_detection_results(
            space_id=request.space_id,
            start_time=request.start_time,
            end_time=request.end_time,
            limit=request.limit
        )
        
        # 转换为响应格式
        detections = []
        for result in results:
            detection = SpaceOccupancyResponse(
                detection_id=result.detection_id,
                camera_id=result.camera_id,
                space_id=result.space_id,
                timestamp=result.timestamp,
                occupancy_status=result.occupancy_status,
                occupancy_rate=result.occupancy_rate,
                person_count=result.person_count,
                capacity=result.capacity,
                space_type=result.space_type,
                confidence=result.confidence,
                detected_activities=result.detected_activities,
                energy_recommendations=result.energy_recommendations,
                usage_duration=result.usage_duration
            )
            detections.append(detection)
        
        return SpaceOccupancyListResponse(
            detections=detections,
            total=len(detections)
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取检测结果失败: {str(e)}")


@router.post("/spaces/stats", response_model=SpaceUsageStatsResponse)
async def get_space_usage_stats(request: SpaceUsageStatsRequest):
    """
    获取空间使用统计
    """
    try:
        stats = await space_occupancy_service.get_space_usage_stats(
            space_id=request.space_id,
            days=request.days
        )
        
        return SpaceUsageStatsResponse(**stats)
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取空间统计失败: {str(e)}")


@router.get("/stats", response_model=SpaceServiceStatsResponse)
async def get_service_stats():
    """
    获取空间占用检测服务统计
    """
    try:
        stats = space_occupancy_service.get_statistics()
        
        return SpaceServiceStatsResponse(**stats)
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取服务统计失败: {str(e)}")


@router.post("/energy/recommendations", response_model=EnergyRecommendationListResponse)
async def get_energy_recommendations(request: EnergyRecommendationRequest):
    """
    获取节能建议
    """
    try:
        recommendations = await space_occupancy_service.get_energy_recommendations(
            space_id=request.space_id,
            hours=request.hours
        )
        
        return EnergyRecommendationListResponse(
            recommendations=recommendations,
            total=len(recommendations)
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取节能建议失败: {str(e)}")


@router.post("/spaces/config", response_model=SpaceConfigResponse)
async def create_space_config(request: SpaceConfigRequest):
    """
    创建空间配置
    """
    try:
        # 创建空间配置
        config = SpaceConfig(
            space_id=request.space_id,
            space_name=request.space_name,
            space_type=request.space_type,
            capacity=request.capacity,
            area_sqm=request.area_sqm,
            operating_hours=request.operating_hours,
            energy_saving_enabled=request.energy_saving_enabled,
            occupancy_threshold=request.occupancy_threshold,
            vacancy_timeout_minutes=request.vacancy_timeout_minutes
        )
        
        # 添加到服务
        space_occupancy_service.add_space_config(config)
        
        return SpaceConfigResponse(
            space_id=config.space_id,
            space_name=config.space_name,
            space_type=config.space_type,
            capacity=config.capacity,
            area_sqm=config.area_sqm,
            operating_hours=config.operating_hours,
            energy_saving_enabled=config.energy_saving_enabled,
            occupancy_threshold=config.occupancy_threshold,
            vacancy_timeout_minutes=config.vacancy_timeout_minutes
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"创建空间配置失败: {str(e)}")


@router.get("/spaces/config", response_model=SpaceConfigListResponse)
async def get_space_configs():
    """
    获取所有空间配置
    """
    try:
        configs = space_occupancy_service.get_space_configs()
        
        # 转换为响应格式
        config_responses = []
        for config in configs:
            config_response = SpaceConfigResponse(
                space_id=config.space_id,
                space_name=config.space_name,
                space_type=config.space_type,
                capacity=config.capacity,
                area_sqm=config.area_sqm,
                operating_hours=config.operating_hours,
                energy_saving_enabled=config.energy_saving_enabled,
                occupancy_threshold=config.occupancy_threshold,
                vacancy_timeout_minutes=config.vacancy_timeout_minutes
            )
            config_responses.append(config_response)
        
        return SpaceConfigListResponse(
            configs=config_responses,
            total=len(config_responses)
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取空间配置失败: {str(e)}")


@router.get("/spaces/config/{space_id}", response_model=SpaceConfigResponse)
async def get_space_config(space_id: str):
    """
    获取指定空间的配置
    """
    try:
        configs = space_occupancy_service.get_space_configs()
        
        # 查找指定空间的配置
        target_config = None
        for config in configs:
            if config.space_id == space_id:
                target_config = config
                break
        
        if not target_config:
            raise HTTPException(status_code=404, detail=f"未找到空间 {space_id} 的配置")
        
        return SpaceConfigResponse(
            space_id=target_config.space_id,
            space_name=target_config.space_name,
            space_type=target_config.space_type,
            capacity=target_config.capacity,
            area_sqm=target_config.area_sqm,
            operating_hours=target_config.operating_hours,
            energy_saving_enabled=target_config.energy_saving_enabled,
            occupancy_threshold=target_config.occupancy_threshold,
            vacancy_timeout_minutes=target_config.vacancy_timeout_minutes
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取空间配置失败: {str(e)}")


@router.put("/spaces/config/{space_id}", response_model=SpaceConfigResponse)
async def update_space_config(space_id: str, request: SpaceConfigRequest):
    """
    更新空间配置
    """
    try:
        # 创建新的配置（覆盖原有配置）
        config = SpaceConfig(
            space_id=space_id,
            space_name=request.space_name,
            space_type=request.space_type,
            capacity=request.capacity,
            area_sqm=request.area_sqm,
            operating_hours=request.operating_hours,
            energy_saving_enabled=request.energy_saving_enabled,
            occupancy_threshold=request.occupancy_threshold,
            vacancy_timeout_minutes=request.vacancy_timeout_minutes
        )
        
        # 更新服务中的配置
        space_occupancy_service.add_space_config(config)
        
        return SpaceConfigResponse(
            space_id=config.space_id,
            space_name=config.space_name,
            space_type=config.space_type,
            capacity=config.capacity,
            area_sqm=config.area_sqm,
            operating_hours=config.operating_hours,
            energy_saving_enabled=config.energy_saving_enabled,
            occupancy_threshold=config.occupancy_threshold,
            vacancy_timeout_minutes=config.vacancy_timeout_minutes
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新空间配置失败: {str(e)}")


@router.delete("/spaces/config/{space_id}")
async def delete_space_config(space_id: str):
    """
    删除空间配置
    """
    try:
        # 检查配置是否存在
        configs = space_occupancy_service.get_space_configs()
        config_exists = any(config.space_id == space_id for config in configs)
        
        if not config_exists:
            raise HTTPException(status_code=404, detail=f"未找到空间 {space_id} 的配置")
        
        # 从服务中删除配置
        if space_id in space_occupancy_service.space_configs:
            del space_occupancy_service.space_configs[space_id]
        
        return {"message": f"空间 {space_id} 的配置已删除"}
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除空间配置失败: {str(e)}")


@router.post("/service/start")
async def start_service():
    """
    启动空间占用检测服务
    """
    try:
        await space_occupancy_service.start_service()
        return {"message": "空间占用检测服务已启动"}
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"启动服务失败: {str(e)}")


@router.post("/service/stop")
async def stop_service():
    """
    停止空间占用检测服务
    """
    try:
        await space_occupancy_service.stop_service()
        return {"message": "空间占用检测服务已停止"}
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"停止服务失败: {str(e)}")


@router.get("/service/status")
async def get_service_status():
    """
    获取空间占用检测服务状态
    """
    try:
        return {
            "running": space_occupancy_service._running,
            "monitoring_interval": space_occupancy_service.monitoring_interval,
            "total_detections": len(space_occupancy_service.detection_results),
            "spaces_monitored": len(set(r.space_id for r in space_occupancy_service.detection_results)),
            "total_space_configs": len(space_occupancy_service.space_configs)
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取服务状态失败: {str(e)}")